<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
        list-style: none;
      }

      #list {
        width: 640px;
        height: 490px;
        margin: 10px auto;
        border: 1px solid #000;
        position: relative;
      }

      li {
        width: 200px;
        height: 150px;
        /* position: absolute;
				left: 10px;
				top: 10px; */
        float: left;
        margin: 10px 0 0 10px;
      }

      li > img {
        display: block;
        width: 100%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <ul id="list">
      <li><img src="../img/avatar.png" alt="" /></li>
      <li><img src="../img/defaultInteriorBackgroundBanner.jpg" alt="" /></li>
      <li><img src="../img/Logo.png" alt="" /></li>
      <li><img src="../img/avatar.png" alt="" /></li>
      <li><img src="../img/defaultInteriorBackgroundBanner.jpg" alt="" /></li>
      <li><img src="../img/avatar.png" alt="" /></li>
      <li><img src="../img/avatar.png" alt="" /></li>
      <li><img src="../img/Logo.png" alt="" /></li>
      <li><img src="../img/defaultInteriorBackgroundBanner.jpg" alt="" /></li>
    </ul>
    <script src="./js/move.js"></script>
    <script type="text/javascript">
      var lis = document.getElementsByTagName("li");

      /* 
			1、跟谁交换位置
				谁：与它重叠多的那一个
				位置：数组中对应需要交换的位置
		*/
      var positions = []; //用来存放lis的偏移量
      var _zIndex = 2;
      //玩数组中插入对应的位置信息
      for (var i = 0; i < lis.length; i++) {
        positions.push([lis[i].offsetLeft, lis[i].offsetTop]);
      }
      console.log(positions);
      for (var i = 0; i < lis.length; i++) {
        //给每一个lis设置对应的位置
        lis[i].style.margin = "0";
        lis[i].style.position = "absolute";
        lis[i].style.left = positions[i][0] + "px";
        lis[i].style.top = positions[i][1] + "px";
      }

      //1、封装拖拽效果
      function drap(obj) {
        //drap(lis[i])
        /* obj: 需要拖动的对象 */
        //1-1、设置容器存放x y轴（初始化）
        var disX = 0;
        var disY = 0;
        //2、绑定按下事件
        obj.onmousedown = function (ev) {
          var ev = ev || window.event;
          ev.preventDefault();
          //2-1、鼠标事件在元素内发生的位置
          disX = ev.clientX - obj.offsetLeft;
          disY = ev.clientY - obj.offsetTop;

          //设置层级
          obj.style.zIndex = _zIndex++; //z-index = zIndex

          //9、调用停止动画
          stopMove(obj);

          //2-2、绑定移动事件
          document.onmousemove = function (ev) {
            var ev = ev || window.event;
            ev.preventDefault();
            //2-3、获取元素实际移动的位置
            var x = ev.clientX - disX;
            var y = ev.clientY - disY;
            //2-4、赋值
            obj.style.left = x + "px";
            obj.style.top = y + "px";

            //8、判断重叠部分多的显示一个边框
            var cha = jc(obj);
            for (var i = 0; i < lis.length; i++) {
              lis[i].style.border = "";
            }
            if (cha) {
              cha.style.border = "2px solid #ff4100";
            }
          };
          //3、释放移动事件 && 交换位置
          document.onmouseup = function () {
            document.onmousemove = null;
            var cha = jc(obj);
            //console.log(cha);
            var temp = 0;
            if (cha) {
              //先做赋值
              // cha.style.left = positions[obj.index][0] + 'px';
              // cha.style.top = positions[obj.index][1] + 'px';
              // obj.style.left = positions[cha.index][0] + 'px';
              // obj.style.top = positions[cha.index][1] + 'px';
              startMove(obj, {
                //json[attr] == json.attr
                left: positions[cha.index][0],
                top: positions[cha.index][1],
              });

              startMove(cha, {
                left: positions[obj.index][0],
                top: positions[obj.index][1],
              });
              cha.style.border = "";
              //再做交换
              temp = obj.index;
              obj.index = cha.index;
              cha.index = temp;
            } else {
              // obj.style.left = positions[obj.index][0] + 'px';
              // obj.style.top = positions[obj.index][1] + 'px';
              startMove(obj, {
                left: positions[obj.index][0],
                top: positions[obj.index][1],
              });
            }
            return false;
          };
        };
      }

      //4、给每一个lis绑定拖拽效果
      for (var i = 0; i < lis.length; i++) {
        lis[i].index = i;
        drap(lis[i]);
      }

      //5、封装碰撞函数
      function boom(obj1, obj2) {
        //obj1的四个方位
        var l1 = obj1.offsetLeft;
        var r1 = l1 + obj1.offsetWidth;
        var t1 = obj1.offsetTop;
        var b1 = t1 + obj1.offsetHeight;

        //obj2的四个方位
        var l2 = obj2.offsetLeft;
        var r2 = l2 + obj2.offsetWidth;
        var t2 = obj2.offsetTop;
        var b2 = t2 + obj2.offsetHeight;

        //碰撞条件：条件成立返回true 反之返回false
        if (b1 < t2 || t1 > b2 || r1 < l2 || l1 > r2) {
          return false;
        } else {
          return true;
        }
      }

      //6、计算斜边
      function xb(obj1, obj2) {
        var a = obj1.offsetLeft - obj2.offsetLeft;
        var b = obj1.offsetTop - obj2.offsetTop;
        return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
        /* 
				Math.sqrt(a*a + b*b);
			*/
      }

      //7、检测跟谁重叠的部分最多
      function jc(obj) {
        //设定比较值
        var val = 9999; //假设值
        var index = -1; //最后一个
        //给每一个obj做判断
        for (var i = 0; i < lis.length; i++) {
          if (boom(obj, lis[i]) && obj != lis[i]) {
            //判断斜边
            var c = xb(obj, lis[i]);
            //console.log(c);
            if (c < val) {
              val = c;
              index = i;
            }
          }
        }
        if (index == -1) {
          return false;
        } else {
          return lis[index];
        }
      }

      // 运动函数
      function startMove(obj, json, endFn) {
        clearInterval(obj.timer);

        obj.timer = setInterval(function () {
          var bBtn = true;

          for (var attr in json) {
            var iCur = 0;

            if (attr == "opacity") {
              if (Math.round(parseFloat(getStyle(obj, attr)) * 100) == 0) {
                iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
              } else {
                iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100) || 100;
              }
            } else {
              iCur = parseInt(getStyle(obj, attr)) || 0;
            }

            var iSpeed = (json[attr] - iCur) / 8;
            iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
            if (iCur != json[attr]) {
              bBtn = false;
            }

            if (attr == "opacity") {
              obj.style.filter = "alpha(opacity=" + (iCur + iSpeed) + ")";
              obj.style.opacity = (iCur + iSpeed) / 100;
            } else {
              obj.style[attr] = iCur + iSpeed + "px";
            }
          }

          if (bBtn) {
            clearInterval(obj.timer);

            if (endFn) {
              endFn.call(obj);
            }
          }
        }, 30);
      }

      function getStyle(obj, attr) {
        if (obj.currentStyle) {
          return obj.currentStyle[attr];
        } else {
          return getComputedStyle(obj, false)[attr];
        }
      }

      function stopMove(obj) {
        clearInterval(obj.timer);
      }
    </script>
  </body>
</html>
